﻿using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Xml;
using System.Windows.Documents;
using System.Text;
using SHomeWorkshop.LunarPresentation.Expressions;
using System.Windows.Data;
using System.Windows.Controls.Primitives;

namespace SHomeWorkshop.LunarPresentation.Dialogs
{
    /// <summary>
    /// Interaction logic for RichTextEditor.xaml
    /// </summary>
    public partial class RichTextEditor : Window
    {
        public RichTextEditor(Expressions.RichText richText, string initializeText)
        {
            InitializeComponent();

            this.initializeText = initializeText;

            //禁用原来的快捷菜单。
            mainRTB.ContextMenu = null;

            this.masterRichText = richText;

            Globals.SwitchInputMethod(true);

            if (Globals.selectedEditor != null)
            {
                if (Globals.selectedEditor.DefaultBackground == Brushes.Transparent)
                {
                    outBorder.Background = Brushes.WhiteSmoke;
                }
                else
                {
                    outBorder.Background = Globals.selectedEditor.DefaultBackground;
                }

                editorTitleBorder.BorderBrush =
                editorTitle.Foreground = Globals.selectedEditor.DefaultForeground;
            }

            InputMethod.SetIsInputMethodEnabled(mainRTB, true);

            //给边框添加变色效果，结果发现有打扰人的反面效果，于是改成只闪动两次。
            Brush myBrush = new SolidColorBrush();

            ColorAnimation myColorAnimation = new ColorAnimation();
            if (Globals.selectedEditor != null &&
                Globals.selectedEditor.ExSelectionAdornerBrush is SolidColorBrush)
            {
                myColorAnimation.From = ((SolidColorBrush)Globals.selectedEditor.ExSelectionAdornerBrush).Color;
            }
            else
            {
                myColorAnimation.From = Colors.Red;
            }

            myColorAnimation.To = Colors.Transparent;
            myColorAnimation.Duration = new Duration(TimeSpan.FromMilliseconds(200));
            myColorAnimation.AutoReverse = true;
            myColorAnimation.RepeatBehavior = new RepeatBehavior(2);

            //将动画应用到画刷（Brush）的“Color”属性。
            myBrush.BeginAnimation(SolidColorBrush.ColorProperty, myColorAnimation);
            outBorder.BorderBrush = myBrush;

            if (richText == null)
            {
                mainRTB.Selection.Text = "没有指定要编辑的富文块！";
                mainRTB.IsEnabled = false;
                btnOk.IsEnabled = false;
                return;
            }

            if (richText.XmlData == null)
            {
                mainRTB.Selection.Text = "没有指定要编辑的富文块！";
                mainRTB.IsEnabled = false;
                btnOk.IsEnabled = false;
                return;
            }

            if (richText.ExBackground == Brushes.Transparent)
            {
                if (richText.Editor.DefaultBackground == Brushes.Transparent)
                {
                    mainRTB.Background = Brushes.White;//如果是编辑器是透明底色，当白色处理，顺为底图是白色底带花纹的。
                }
                else
                {
                    mainRTB.Background = richText.Editor.DefaultBackground;
                }
            }
            else
            {
                mainRTB.Background = richText.ExBackground;
            }

            mainRTB.Foreground = richText.ExForeground;
            mainRTB.CaretBrush = richText.Editor.SubPanelSelectionAdornerBrush;
            mainRTB.SelectionBrush = richText.Editor.ExSelectionAdornerBrush;

            //考虑到初始字号。放到Loaded事件中。
            //ReadLines();
            this.Loaded += new RoutedEventHandler(RichTextEditor_Loaded);

            mainRTB.SelectAll();
            mainRTB.Focus();

            colorPickerPopup.Child = colorPicker;
            colorPicker.Closed += new EventHandler<EventArgs>(colorPicker_Closed);
            colorPicker.ColorPicked += new EventHandler<ColorPickedEventArgs>(colorPicker_ColorPicked);

            foreach (object item in Globals.MainWindow.cbFont.Items)
            {
                cbFont.Items.Add(item);
            }

            if (cbFont.Items.Contains(Globals.SysFontFamily))
            {
                cbFont.SelectedItem = Globals.SysFontFamily;
            }
        }

        void RichTextEditor_Loaded(object sender, RoutedEventArgs e)
        {
            if (initializeText == null || initializeText.Length <= 0)
            {
                ReadLines();
                this.mainRTB.SelectAll();
            }
            else
            {
                this.mainRTB.SelectAll();
                this.mainRTB.Selection.Text = "";
                this.mainRTB.AppendText(initializeText);
            }
        }

        private void ReadLines()
        {
            XmlNodeList nlist = masterRichText.XmlData.SelectNodes("Text");

            Paragraph newParagraph = new Paragraph();
            mainDoc.Blocks.Add(newParagraph);

            foreach (XmlNode node in nlist)
            {
                if (node.InnerText == null || node.InnerText.Length == 0)
                {
                    newParagraph = new Paragraph();
                    mainDoc.Blocks.Add(newParagraph);
                    continue;
                }

                Run run = new Run(node.InnerText);

                //读取出所有格式信息。
                //取文本特性
                XmlAttribute attrForeground = node.GetAttribute("Foreground");
                if (attrForeground != null)
                {
                    Brush foreground = ColorPicker.GetBrushByName(attrForeground.Value);
                    if (foreground != null)
                        run.Foreground = foreground;
                }

                XmlAttribute attrBackground = node.GetAttribute("Background");
                if (attrBackground != null)
                {
                    Brush background = ColorPicker.GetBrushByName(attrBackground.Value);
                    if (background != null)
                        run.Background = background;
                }
                else
                {
                    run.Background = Brushes.Transparent;
                }

                XmlAttribute attrFontWeight = node.GetAttribute("FontWeight");
                if (attrFontWeight != null && attrFontWeight.Value == "Bold")
                {
                    run.FontWeight = FontWeights.Bold;
                }

                XmlAttribute attrFontStyle = node.GetAttribute("FontStyle");
                if (attrFontStyle != null && attrFontStyle.Value == "Italic")
                {
                    run.FontStyle = FontStyles.Italic;
                }

                XmlAttribute attrUnderLine = node.GetAttribute("UnderLine");
                if (attrUnderLine != null && attrUnderLine.Value == "True")
                {
                    run.TextDecorations.Add(TextDecorations.Underline);
                }

                XmlAttribute attrStrikeLine = node.GetAttribute("StrikeLine");
                if (attrStrikeLine != null && attrStrikeLine.Value == "True")
                {
                    run.TextDecorations.Add(TextDecorations.Strikethrough);
                }

                XmlAttribute attrFontName = node.GetAttribute("FontName");
                if (attrFontName != null)
                {
                    FontFamily fontFamily = new FontFamily(attrFontName.Value);
                    if (fontFamily != null)
                        run.FontFamily = fontFamily;
                }

                XmlAttribute attrBaseLineAlignment = node.GetAttribute("BaseLineAlignment");
                if (attrBaseLineAlignment != null)
                {
                    switch (attrBaseLineAlignment.Value)
                    {
                        case "Top":
                            {
                                run.BaselineAlignment = BaselineAlignment.Top;
                                run.FontSize = mainRTB.FontSize / 2;
                                break;
                            }
                        case "Bottom":
                            {
                                run.BaselineAlignment = BaselineAlignment.Bottom;
                                run.FontSize = mainRTB.FontSize / 2;
                                break;
                            }
                        default:
                            {
                                run.BaselineAlignment = BaselineAlignment.Baseline;
                                break;
                            }
                    }
                }

                newParagraph.Inlines.Add(run);
            }
        }

        private bool WriteLinesToRichTextXmlData()
        {
            if (masterRichText == null || masterRichText.XmlData == null)
            {
                MessageBox.Show("发现意外错误，没有传入富文本块，或传入的富文本块没有后台数据节点！",
                    Globals.appName, MessageBoxButton.OK, MessageBoxImage.Warning);
                return false;
            }

            StringBuilder sb = new StringBuilder();

            foreach (Block block in mainDoc.Blocks)
            {
                Paragraph paragraph = block as Paragraph;
                if (paragraph == null) continue;

                #region 处理空行
                if (paragraph.Inlines.Count <= 0 || paragraph.Inlines.FirstInline == null)//否则本身就是换行。
                {
                    sb.Append("<Text />");//<Text />表示换行。
                    continue;
                }

                #endregion

                foreach (Inline inline in paragraph.Inlines)
                {
                    Run run = inline as Run;
                    if (run != null && run.Text.Length > 0)
                    {
                        sb.Append("<Text ");//不完整的tab，因为要考虑特性。

                        if (inline == paragraph.Inlines.FirstInline)
                        {
                            sb.Append("TextAlignment=\"");
                            sb.Append(paragraph.TextAlignment.ToString());
                            sb.Append("\" ");
                        }

                        //取出各格式特性值。
                        sb.Append("Foreground=\"");
                        sb.Append(ColorPicker.GetBrushName(run.Foreground));
                        sb.Append("\" ");

                        sb.Append("Background=\"");
                        sb.Append(ColorPicker.GetBrushName(run.Background));
                        sb.Append("\" ");

                        sb.Append("FontWeight=\"");
                        sb.Append(run.FontWeight.ToString());
                        sb.Append("\" ");

                        sb.Append("FontStyle=\"");
                        sb.Append(run.FontStyle.ToString());
                        sb.Append("\" ");

                        sb.Append("FontName=\"");
                        sb.Append(run.FontFamily.Source);
                        sb.Append("\" ");

                        if (run.TextDecorations != null && run.TextDecorations.Count > 0)
                        {
                            bool isStrikeLine = false;
                            bool isUnderLine = false;
                            foreach (TextDecoration td in run.TextDecorations)
                            {
                                if (td.Location == TextDecorationLocation.Underline)
                                {
                                    isUnderLine = true;
                                }
                                else if (td.Location == TextDecorationLocation.Strikethrough)
                                {
                                    isStrikeLine = true;
                                }
                            }

                            if (isStrikeLine)
                            {
                                sb.Append("StrikeLine=\"True\" ");
                            }

                            if (isUnderLine)
                            {
                                sb.Append("UnderLine=\"True\" ");
                            }
                        }

                        sb.Append("BaseLineAlignment=\"");
                        sb.Append(run.BaselineAlignment.ToString());
                        sb.Append("\" ");

                        sb.Append(">");
                        sb.Append(ReplaceXmlChars(run.Text));
                        sb.Append("</Text>");
                    }
                }

                sb.Append("<Text />");//每段末尾添加<Text />表示换行。
            }

            string s = sb.ToString();
            if (s.EndsWith("<Text />"))
            {
                s = s.Substring(0, s.Length - 8);
            }

            ModifingItem mi = new ModifingItem()
            {
                OldSelectedExID = masterRichText.ExID,
                NewSelectedExID = masterRichText.ExID
            };

            Action actXmlDataInnerXml = new Action(masterRichText.ExID, -1, masterRichText.GetType().Name,
                "XmlDataInnerXml", masterRichText.XmlData.InnerXml, s);

            //注意此处的顺序。不能在Action之前清除。
            masterRichText.XmlData.InnerXml = "";//先清除所有子节点。

            masterRichText.XmlData.InnerXml = s;

            mi.Add(actXmlDataInnerXml);

            masterRichText.UpdateTextBlockFromXmlData();

            masterRichText.Editor.Do(mi);
            masterRichText.Editor.IsModified = true;
            return true;
        }

        internal static string ReplaceXmlChars(string source)
        {
            if (source == null) return null;
            if (source.Length <= 0) return string.Empty;

            //Xml预定的转义字符有五个，只有“<”和“&”是严格禁止使用的。
            string result = source.Replace("&", "&amp;");
            result = result.Replace("<", "&lt;");
            result = result.Replace(">", "&gt;");
            result = result.Replace("'", "&apos;");
            result = result.Replace("\"", "&quot;");
            return result;
        }

        /// <summary>
        /// 将Xml文本中的&lt;和&amp;转换回小于号和&符。
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>
        internal static string RestoreXmlChars(string source)
        {
            if (source == null) return null;
            if (source.Length <= 0) return string.Empty;

            //Xml预定的转义字符有五个，只有“<”和“&”是严格禁止使用的。
            string result = source.Replace("&quot;", "\"");
            result = result.Replace("&apos;", "'");
            result = result.Replace("&gt;", ">");
            result = result.Replace("&lt;", "<");
            result = result.Replace("&amp;", "&");
            return result;
        }

        private Expressions.RichText masterRichText;

        public Expressions.RichText MasterRichText
        {
            get { return masterRichText; }
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            mainRTB.Selection.Text = (sender as Button).Content.ToString();
        }

        private void btnOk_Click(object sender, RoutedEventArgs e)
        {
            this.DialogResult = true;

            Globals.SwitchInputMethod(false);

            WriteLinesToRichTextXmlData();

            this.Close();
        }

        #region 透明窗口代码
        //protected override void OnSourceInitialized(EventArgs e)
        //{
        //    base.OnSourceInitialized(e);

        //    if (System.Environment.OSVersion.Version.Major >= 6)//Vista及更高版本的操作系统。
        //    {
        //        // 这可在 SourceInitialized 事件前完成:
        //        SHomeWorkshop.LunarPresentation.AeroGlassLib.AeroGlassForWPFWindow.ExtendGlassFrame(this,
        //            new SHomeWorkshop.LunarPresentation.AeroGlassLib.MARGINS(0, 0, 50, 28));

        //        IntPtr hwnd = new WindowInteropHelper(this).Handle;
        //        HwndSource.FromHwnd(hwnd).AddHook(new HwndSourceHook(WndProc));
        //    }
        //}

        //private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
        //{
        //    if (msg == WM_DWMCOMPOSITIONCHANGED)
        //    {
        //        // 重启玻璃效果:
        //        SHomeWorkshop.LunarPresentation.AeroGlassLib.AeroGlassForWPFWindow.ExtendGlassFrame(this,
        //             new SHomeWorkshop.LunarPresentation.AeroGlassLib.MARGINS(0, 0, 50, 28));
        //        handled = true;
        //    }
        //    return IntPtr.Zero;
        //}

        //private const int WM_DWMCOMPOSITIONCHANGED = 0x031E;

        #endregion

        private void fontSizeSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
        {
            mainRTB.FontSize = fontSizeSlider.Value;
        }

        private void btnCancel_Click(object sender, RoutedEventArgs e)
        {
            this.DialogResult = false;

            Globals.SwitchInputMethod(false);

            this.Close();
        }

        private void btnCut_Click(object sender, RoutedEventArgs e)
        {
            mainRTB.Cut();
        }

        private void btnCopy_Click(object sender, RoutedEventArgs e)
        {
            mainRTB.Copy();
        }

        private void btnPaste_Click(object sender, RoutedEventArgs e)
        {
            mainRTB.Paste();
        }

        private void btnBold_Click(object sender, RoutedEventArgs e)
        {
            FontWeight fw = (FontWeight)mainRTB.Selection.GetPropertyValue(TextElement.FontWeightProperty);

            if (fw == FontWeights.Bold)
            {
                mainRTB.Selection.ApplyPropertyValue(TextElement.FontWeightProperty, FontWeights.Normal);
            }
            else
            {
                mainRTB.Selection.ApplyPropertyValue(TextElement.FontWeightProperty, FontWeights.Bold);
            }
        }

        private void btnItalic_Click(object sender, RoutedEventArgs e)
        {
            FontStyle fs = (FontStyle)mainRTB.Selection.GetPropertyValue(TextElement.FontStyleProperty);

            if (fs == FontStyles.Italic)
            {
                mainRTB.Selection.ApplyPropertyValue(TextElement.FontStyleProperty, FontStyles.Normal);
            }
            else
            {
                mainRTB.Selection.ApplyPropertyValue(TextElement.FontStyleProperty, FontStyles.Italic);
            }
        }

        private void btnUnderLine_Click(object sender, RoutedEventArgs e)
        {
            TextDecorationCollection tc = mainRTB.Selection.GetPropertyValue(Inline.TextDecorationsProperty) as TextDecorationCollection;

            bool isUnderline = false;

            var obj = mainRTB.Selection.GetPropertyValue(Inline.TextDecorationsProperty);

            TextDecorationCollection tdCollection = obj as TextDecorationCollection;

            if (tdCollection != null || tdCollection.Count > 0)
            {
                foreach (TextDecoration td in tdCollection)
                {
                    if (td.Location == TextDecorationLocation.Underline)
                    {
                        isUnderline = true;
                        break;
                    }
                }
            }

            TextDecorationCollection newTC = new TextDecorationCollection();

            if (isUnderline)
            {
                for (int i = tdCollection.Count - 1; i >= 0; i--)
                {
                    TextDecoration td = tdCollection[i];
                    if (td.Location == TextDecorationLocation.Underline)
                    {
                        continue;
                    }

                    TextDecoration newTD = new TextDecoration() { Location = td.Location };
                    newTC.Add(newTD);
                }
            }
            else
            {
                for (int i = tdCollection.Count - 1; i >= 0; i--)
                {
                    TextDecoration td = tdCollection[i];
                    TextDecoration newTD = new TextDecoration() { Location = td.Location };
                    newTC.Add(newTD);
                }

                newTC.Add(new TextDecoration() { Location = TextDecorationLocation.Underline });
            }

            mainRTB.Selection.ApplyPropertyValue(Inline.TextDecorationsProperty, newTC);
        }

        private void btnStrikeLine_Click(object sender, RoutedEventArgs e)
        {
            TextDecorationCollection tc = mainRTB.Selection.GetPropertyValue(Inline.TextDecorationsProperty) as TextDecorationCollection;

            bool isStrikeline = false;

            var obj = mainRTB.Selection.GetPropertyValue(Inline.TextDecorationsProperty);

            TextDecorationCollection tdCollection = obj as TextDecorationCollection;

            if (tdCollection != null || tdCollection.Count > 0)
            {
                foreach (TextDecoration td in tdCollection)
                {
                    if (td.Location == TextDecorationLocation.Strikethrough)
                    {
                        isStrikeline = true;
                        break;
                    }
                }
            }

            TextDecorationCollection newTC = new TextDecorationCollection();

            if (isStrikeline)
            {
                for (int i = tdCollection.Count - 1; i >= 0; i--)
                {
                    TextDecoration td = tdCollection[i];
                    if (td.Location == TextDecorationLocation.Strikethrough)
                    {
                        continue;
                    }

                    TextDecoration newTD = new TextDecoration() { Location = td.Location };
                    newTC.Add(newTD);
                }
            }
            else
            {
                for (int i = tdCollection.Count - 1; i >= 0; i--)
                {
                    TextDecoration td = tdCollection[i];
                    TextDecoration newTD = new TextDecoration() { Location = td.Location };
                    newTC.Add(newTD);
                }

                newTC.Add(new TextDecoration() { Location = TextDecorationLocation.Strikethrough });
            }

            mainRTB.Selection.ApplyPropertyValue(Inline.TextDecorationsProperty, newTC);
        }


        private Popup colorPickerPopup = new Popup() { IsOpen = false };

        private readonly ColorPicker colorPicker = new ColorPicker();

        private void colorPicker_Closed(object sender, EventArgs e)
        {
            colorPickerPopup.IsOpen = false;
        }

        private void colorPicker_ColorPicked(object sender, ColorPickedEventArgs e)
        {
            colorPickerPopup.IsOpen = false;

            SetTextColor((sender as ColorPicker).DestAction, e.PickedColor);
        }

        private void SetTextColor(ColorPicker.Destination dest, Brush newBrush)
        {
            switch (dest)
            {
                case ColorPicker.Destination.Foreground:
                    {
                        TextRange range = new TextRange(mainRTB.Selection.Start, mainRTB.Selection.End);
                        range.ApplyPropertyValue(FlowDocument.ForegroundProperty, newBrush);
                        break;
                    }
                case ColorPicker.Destination.Background:
                    {
                        TextRange range = new TextRange(mainRTB.Selection.Start, mainRTB.Selection.End);
                        range.ApplyPropertyValue(FlowDocument.BackgroundProperty, newBrush);
                        break;
                    }
            }
        }

        #region 用于定位拾色器的两个绑定

        private Binding textForegroundBinding = null;

        private Binding textBackgroundBinding = null;

        #endregion

        private void btnForeground_Click(object sender, RoutedEventArgs e)
        {
            if (colorPickerPopup.IsOpen)
            {
                colorPickerPopup.IsOpen = false;
            }

            if (textForegroundBinding == null)
            {
                textForegroundBinding = new Binding();
                textForegroundBinding.Source = btnForeground;
            }

            colorPickerPopup.SetBinding(Popup.PlacementTargetProperty, textForegroundBinding);

            ColorPicker colorpicker = colorPickerPopup.Child as ColorPicker;
            colorpicker.DestAction = ColorPicker.Destination.Foreground;
            colorPickerPopup.IsOpen = true;
        }

        private void btnBackground_Click(object sender, RoutedEventArgs e)
        {
            if (colorPickerPopup.IsOpen)
            {
                colorPickerPopup.IsOpen = false;
            }

            if (textBackgroundBinding == null)
            {
                textBackgroundBinding = new Binding();
                textBackgroundBinding.Source = btnBackground;
            }

            colorPickerPopup.SetBinding(Popup.PlacementTargetProperty, textBackgroundBinding);

            ColorPicker colorpicker = colorPickerPopup.Child as ColorPicker;
            colorpicker.DestAction = ColorPicker.Destination.Background;
            colorPickerPopup.IsOpen = true;
        }

        private void btnTopMark_Click(object sender, RoutedEventArgs e)
        {
            var currentAlignment = mainRTB.Selection.GetPropertyValue(Inline.BaselineAlignmentProperty);

            BaselineAlignment newAlignment;

            if (currentAlignment == DependencyProperty.UnsetValue)
            {
                newAlignment = BaselineAlignment.Top;
            }
            else
            {
                newAlignment =
                    ((BaselineAlignment)currentAlignment == BaselineAlignment.Top) ?
                        BaselineAlignment.Baseline : BaselineAlignment.Top;
            }

            mainRTB.Selection.ApplyPropertyValue(Inline.BaselineAlignmentProperty, newAlignment);

            if (newAlignment == BaselineAlignment.Baseline)
            {
                mainRTB.Selection.ApplyPropertyValue(TextElement.FontSizeProperty, mainRTB.FontSize);
            }
            else
            {
                mainRTB.Selection.ApplyPropertyValue(TextElement.FontSizeProperty, mainRTB.FontSize / 2);
            }
        }

        private void btnBottomMark_Click(object sender, RoutedEventArgs e)
        {
            var currentAlignment = mainRTB.Selection.GetPropertyValue(Inline.BaselineAlignmentProperty);

            BaselineAlignment newAlignment;

            if (currentAlignment == DependencyProperty.UnsetValue)
            {
                newAlignment = BaselineAlignment.Bottom;
            }
            else
            {
                newAlignment =
                ((BaselineAlignment)currentAlignment == BaselineAlignment.Bottom) ?
                    BaselineAlignment.Baseline : BaselineAlignment.Bottom;
            }

            mainRTB.Selection.ApplyPropertyValue(Inline.BaselineAlignmentProperty, newAlignment);

            if (newAlignment == BaselineAlignment.Baseline)
            {
                mainRTB.Selection.ApplyPropertyValue(TextElement.FontSizeProperty, mainRTB.FontSize);
            }
            else
            {
                mainRTB.Selection.ApplyPropertyValue(TextElement.FontSizeProperty, mainRTB.FontSize / 2);
            }
        }

        /// <summary>
        /// 选中文本时，读取字体名称。此地应避免循环设定字体。
        /// </summary>
        private bool dontChangeFont = false;

        private string initializeText;

        private void cbFont_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            //组合框中只有字体名称
            if (dontChangeFont) return;

            FontFamily ff = new FontFamily(cbFont.SelectedItem as string);
            mainRTB.Selection.ApplyPropertyValue(TextElement.FontFamilyProperty, ff);
        }

        private void btnUndo_Click(object sender, RoutedEventArgs e)
        {
            if (mainRTB.CanUndo)
            {
                mainRTB.Undo();
            }
        }

        private void btnRedo_Click(object sender, RoutedEventArgs e)
        {
            if (mainRTB.CanRedo)
            {
                mainRTB.Redo();
            }
        }

        private void mainRTB_SelectionChanged(object sender, RoutedEventArgs e)
        {
            FontFamily ff = mainRTB.Selection.GetPropertyValue(TextElement.FontFamilyProperty) as FontFamily;
            if (ff == null) return;

            if (cbFont.Items.Contains(ff.Source))
            {
                dontChangeFont = true;
                cbFont.SelectedItem = ff.Source;
                dontChangeFont = false;
            }

            var ofs = mainRTB.Selection.GetPropertyValue(TextElement.FontStyleProperty);
            if (ofs is FontStyle)
            {
                FontStyle fs = (FontStyle)ofs;
                if (fs == FontStyles.Italic)
                {
                    btnItalic.IsChecked = true;
                }
                else btnItalic.IsChecked = false;
            }
            else btnItalic.IsChecked = false;

            var ofw = mainRTB.Selection.GetPropertyValue(TextElement.FontWeightProperty);
            if (ofw is FontWeight)
            {
                FontWeight fw = (FontWeight)ofw;
                if (fw == FontWeights.Bold)
                {
                    btnBold.IsChecked = true;
                }
                else btnBold.IsChecked = false;
            }
            else btnBold.IsChecked = false;

            TextDecorationCollection tc = mainRTB.Selection.GetPropertyValue(Inline.TextDecorationsProperty) as TextDecorationCollection;
            if (tc == null)
            {
                btnUnderLine.IsChecked = false;
                btnStrikeLine.IsChecked = false;
            }
            else
            {
                bool isUnderLine = false;
                bool isStrikeLine = false;
                foreach (TextDecoration td in tc)
                {
                    if (td.Location == TextDecorationLocation.Underline)
                    {
                        isUnderLine = true; break;
                    }
                }

                foreach (TextDecoration td in tc)
                {
                    if (td.Location == TextDecorationLocation.Strikethrough)
                    {
                        isStrikeLine = true;
                    }
                }

                btnUnderLine.IsChecked = isUnderLine;
                btnStrikeLine.IsChecked = isStrikeLine;
            }
        }

        private void mainRTB_KeyUp(object sender, KeyEventArgs e)
        {
            bool isShift = false, isCtrl = false;
            KeyboardDevice kd = e.KeyboardDevice;

            if ((kd.GetKeyStates(Key.LeftShift) & KeyStates.Down) > 0 ||
                (kd.GetKeyStates(Key.RightShift) & KeyStates.Down) > 0)
            {
                isShift = true;
            }

            if ((kd.GetKeyStates(Key.LeftCtrl) & KeyStates.Down) > 0 ||
                (kd.GetKeyStates(Key.RightCtrl) & KeyStates.Down) > 0)
            {
                isCtrl = true;
            }

            if (e.Key == Key.OemPlus)
            {
                if (isCtrl)
                {
                    if (isShift)
                    {
                        btnBottomMark_Click(null, null);
                        e.Handled = true;
                    }
                    else
                    {
                        btnTopMark_Click(null, null);
                        e.Handled = true;
                    }
                }
            }
            else if (e.Key == Key.T)
            {
                if (isCtrl && !isShift)
                {
                    btnStrikeLine_Click(null, null);
                    e.Handled = true;
                }
            }
        }

        private void mainRTB_PreviewKeyDown(object sender, KeyEventArgs e)
        {
            bool isShift = false, isCtrl = false;
            KeyboardDevice kd = e.KeyboardDevice;

            if ((kd.GetKeyStates(Key.LeftShift) & KeyStates.Down) > 0 ||
                (kd.GetKeyStates(Key.RightShift) & KeyStates.Down) > 0)
            {
                isShift = true;
            }

            if ((kd.GetKeyStates(Key.LeftCtrl) & KeyStates.Down) > 0 ||
                (kd.GetKeyStates(Key.RightCtrl) & KeyStates.Down) > 0)
            {
                isCtrl = true;
            }

            if (e.Key == Key.V && isCtrl && isShift == false)
            {
                mainRTB.Selection.Text = Clipboard.GetText(TextDataFormat.UnicodeText);
                TextRange sel = mainRTB.Selection;
                sel.Select(sel.End, sel.End);
                e.Handled = true;
            }
        }

        private void Window_PreviewKeyDown(object sender, KeyEventArgs e)
        {
            bool isShift = false, isCtrl = false;
            KeyboardDevice kd = e.KeyboardDevice;

            if ((kd.GetKeyStates(Key.LeftShift) & KeyStates.Down) > 0 ||
                (kd.GetKeyStates(Key.RightShift) & KeyStates.Down) > 0)
            {
                isShift = true;
            }

            if ((kd.GetKeyStates(Key.LeftCtrl) & KeyStates.Down) > 0 ||
                (kd.GetKeyStates(Key.RightCtrl) & KeyStates.Down) > 0)
            {
                isCtrl = true;
            }

            if (e.Key == Key.Enter)
            {
                if (isCtrl || isShift)
                {
                    //mainRTB.Selection.Text = "\r\n";
                    TextRange tr = new TextRange(mainRTB.Selection.Start, mainRTB.Selection.End);
                    tr.Text = "\r\n";

                    mainRTB.CaretPosition = tr.End;

                    e.Handled = true;
                }
                else
                {
                    btnOk_Click(this, e);
                    e.Handled = true;
                }
            }

            //2011年11月26日支持富文本块内部文本右对齐，已无必要再屏蔽这三个快捷键。
            //if (e.Key == Key.E || e.Key == Key.L || e.Key == Key.R)
            //{
            //    if (isCtrl)
            //    {
            //        e.Handled = true; return;
            //    }
            //}
        }

        //private void inputTextBox_PreviewKeyDown(object sender, KeyEventArgs e)
        //{
        //    bool isCtrl = false;

        //    KeyboardDevice kd = e.KeyboardDevice;

        //    if ((kd.GetKeyStates(Key.LeftCtrl) & KeyStates.Down) > 0 ||
        //        (kd.GetKeyStates(Key.RightCtrl) & KeyStates.Down) > 0)
        //    {
        //        isCtrl = true;
        //    }

        //    switch (e.Key)
        //    {
        //        case Key.Up:
        //            {
        //                if (isCtrl)
        //                {
        //                    if (Globals.selectedEditor != null)
        //                    {
        //                        Globals.selectedEditor.BaseScrolledViewer.LineUp();
        //                    }
        //                    e.Handled = true;
        //                }
        //                break;
        //            }
        //        case Key.Down:
        //            {
        //                if (isCtrl)
        //                {
        //                    if (Globals.selectedEditor != null)
        //                    {
        //                        Globals.selectedEditor.BaseScrolledViewer.LineDown();
        //                    }
        //                    e.Handled = true;
        //                }
        //                break;
        //            }
        //        case Key.Left:
        //            {
        //                if (isCtrl)
        //                {
        //                    if (Globals.selectedEditor != null)
        //                    {
        //                        Globals.selectedEditor.BaseScrolledViewer.LineLeft();
        //                    }
        //                    e.Handled = true;
        //                }
        //                break;
        //            }
        //        case Key.Right:
        //            {
        //                if (isCtrl)
        //                {
        //                    if (Globals.selectedEditor != null)
        //                    {
        //                        Globals.selectedEditor.BaseScrolledViewer.LineRight();
        //                    }
        //                    e.Handled = true;
        //                }
        //                break;
        //            }
        //    }
        //}
    }
}
